package com.git.contractmanagement.controller;


import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.git.contractmanagement.common.LoginResult;
import com.git.contractmanagement.common.Result;
import com.git.contractmanagement.entity.User;
import com.git.contractmanagement.entity.vo.UserVO;
import com.git.contractmanagement.entity.dto.ChangePasswordDTO;
import com.git.contractmanagement.entity.dto.EnrollDTO;
import com.git.contractmanagement.entity.dto.LoginDTO;
import com.git.contractmanagement.service.UserService;
import com.git.contractmanagement.service.OnlineUserService;
import com.git.contractmanagement.util.PasswordUtil;
import com.git.contractmanagement.util.VerifyUtil;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;


@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;
    
    @Resource
    private OnlineUserService onlineUserService;
    
    /***
     * 登录
     * @param loginDTO
     * @return
     */
    @PostMapping("/login")
    public Result login(@RequestBody LoginDTO loginDTO) {
        User user = userService.login(loginDTO.getUsername(), loginDTO.getPassword());
        if (user == null) {
            return Result.error("用户名或密码错误");
        }
        // sa-Token 登录：传入 user id
        StpUtil.login(user.getId());
        // 添加用户到在线用户列表
        onlineUserService.addUser(user.getId());
        // 获取 token
        String token = StpUtil.getTokenValue();
        // 返回用户信息 + token
        user.setPassword(null);
        return Result.success(new LoginResult(user, token));
    }
    /**
     * 用户注册
     * @param enrollDTO 注册信息
     * @return
     */
    @PostMapping("/register")
    public Result register(@RequestBody EnrollDTO enrollDTO) {
        // 1. 基础非空校验
        if (enrollDTO == null) {
            return Result.error("注册信息不能为空");
        }
        if (enrollDTO.getUsername() == null || enrollDTO.getUsername().trim().isEmpty()) {
            return Result.error("用户名不能为空");
        }
        if (enrollDTO.getPassword() == null || enrollDTO.getPassword().trim().isEmpty()) {
            return Result.error("密码不能为空");
        }
        if (enrollDTO.getConfirmpassword() == null || enrollDTO.getConfirmpassword().trim().isEmpty()) {
            return Result.error("确认密码不能为空");
        }

        // 2. 校验两次密码是否一致
        if (!enrollDTO.getPassword().equals(enrollDTO.getConfirmpassword())) {
            return Result.error("两次输入的密码不一致");
        }

        // 3. 检查用户名是否已存在
        User existingUser = userService.getOne(
                new QueryWrapper<User>().eq("username", enrollDTO.getUsername())
        );
        if (existingUser != null) {
            return Result.error("用户名已存在");
        }

        // 4. 创建新用户对象
        User user = new User();
        user.setUsername(enrollDTO.getUsername());
        user.setPassword(PasswordUtil.encode(enrollDTO.getPassword())); // 加密密码

        // 5. 可选：设置默认角色或其他默认字段（根据你的业务）
        user.setRole("USER"); // 示例

        // 6. 保存用户
        boolean saved = userService.save(user);
        if (!saved) {
            return Result.error("注册失败，请稍后重试");
        }
        return Result.success("注册成功");
    }
    /**
     * 添加用户
     *
     * @param user
     * @return
     */
    @PostMapping("/addUser")
    @SaCheckRole("ADMIN")
    public Result save(@RequestBody User user) {
        // 1. 基础非空校验
        if (user == null) {
            return Result.error("用户信息不能为空");
        }
        if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {
            return Result.error("用户名不能为空");
        }
        if (user.getPassword() == null || user.getPassword().trim().isEmpty()) {
            return Result.error("密码不能为空");
        }
        // 2. 手机号校验
        if (user.getPhone() == null || user.getPhone().trim().isEmpty()) {
            return Result.error("手机号不能为空");
        }
        if (!VerifyUtil.verifyFormatPhone(user.getPhone())) {
            return Result.error("手机号格式不正确");
        }
        // 3. 身份证校验（如果传了）
        if (user.getIdentityCard() != null && !user.getIdentityCard().trim().isEmpty()) {
            if (!VerifyUtil.isValidIdCard(user.getIdentityCard())) {
                return Result.error("身份证号码格式不正确");
            }
        }
        // 4. 检查手机号是否已存在（推荐）
        User existingUserByPhone = userService.getOne(
                new QueryWrapper<User>().eq("phone", user.getPhone())
        );
        if (existingUserByPhone != null) {
            return Result.error("手机号已注册");
        }
        // 5. 检查身份证是否已存在（如果传了）
        if (user.getIdentityCard() != null && !user.getIdentityCard().trim().isEmpty()) {
            User existingUserByIdCard = userService.getOne(
                    new QueryWrapper<User>().eq("identity_card", user.getIdentityCard())
            );
            if (existingUserByIdCard != null) {
                return Result.error("身份证号码已被注册");
            }
        }

        // 6. 密码加密
        user.setPassword(PasswordUtil.encode(user.getPassword()));

        // 7. 执行保存
        boolean saved = userService.save(user);
        if (!saved) {
            return Result.error("用户保存失败，请稍后重试");
        }
        return Result.success("用户添加成功");
    }

    @Value("${file.upload-dir}")
    private String uploadDir;
    /**
     * 上传头像功能
     * @param avatarFile
     * @return
     */
    @PostMapping("/update/avatar")
    @SaCheckLogin
    public Result updateAvatar(@RequestParam("avatar") MultipartFile avatarFile) {
        if (avatarFile == null || avatarFile.isEmpty()) {
            return Result.error("请选择要上传的头像文件");
        }

        String originalFilename = avatarFile.getOriginalFilename();
        if (originalFilename == null || originalFilename.trim().isEmpty()) {
            return Result.error("文件名无效");
        }

        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        if (!".png".equals(fileExtension) && !".gif".equals(fileExtension)) {
            return Result.error("仅支持 PNG 和 GIF 格式的图片");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        User currentUser = userService.getById(currentUserId);
        if (currentUser == null) {
            return Result.error("用户不存在");
        }

        try {
            String newFileName = "avatar_" + currentUserId + "_" + System.currentTimeMillis() + fileExtension;

            File dir = new File(uploadDir);
            if (!dir.exists() && !dir.mkdirs()) {
                return Result.error("上传目录创建失败，请检查路径和权限：" + uploadDir);
            }

            File destFile = new File(dir, newFileName);
            avatarFile.transferTo(destFile);

            // 删除旧头像文件
            String oldImagePath = currentUser.getImage();
            if (oldImagePath != null && oldImagePath.startsWith("/uploads/")) {
                // 提取文件名
                String oldFileName = oldImagePath.substring(oldImagePath.lastIndexOf("/") + 1);
                File oldFile = new File(dir, oldFileName);
                if (oldFile.exists() && !oldFile.delete()) {
                    // 删除失败可以记录日志，但不阻断主流程（避免因删文件失败导致用户无法换头像）
                    System.err.println("旧头像文件删除失败: " + oldFile.getAbsolutePath());
                }
            }

            // 注意：这里 URL 路径需和 WebMvcConfigurer 中的映射一致
            currentUser.setImage("/uploads/" + newFileName);
            boolean updated = userService.updateById(currentUser);

            if (!updated) {
                destFile.delete();
                return Result.error("头像设置失败");
            }

            return Result.success("/uploads/" + newFileName);

        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("头像上传失败：" + e.getMessage());
        }
    }

    /**
     * 修改用户信息
     * @param user
     * @return
     */
    @PutMapping("/update")
    @SaCheckLogin
    public Result update(@RequestBody User user) {
        Long currentUserId = StpUtil.getLoginIdAsLong();
        
        // 获取数据库中的原始用户信息
        User originalUser = userService.getById(user.getId());
        if (originalUser == null) {
            return Result.error("用户不存在");
        }
        
        // 检查是否有权限修改该用户信息
        if (!currentUserId.equals(user.getId())) {
            // 非本人操作，需要检查是否为管理员
            User currentUser = userService.getById(currentUserId);
            if (!"ADMIN".equals(currentUser.getRole())) {
                return Result.error("无权修改他人信息");
            }
            
            // 管理员操作，只能修改角色和特定字段
            if (user.getRole() != null && !user.getRole().equals(originalUser.getRole())) {
                // 角色变更
                originalUser.setRole(user.getRole());
            }
        } else {
            // 本人操作，只能修改个人信息，不能修改角色
            originalUser.setEmail(user.getEmail());
            originalUser.setPhone(user.getPhone());
            originalUser.setUnit(user.getUnit());
            originalUser.setIndustry(user.getIndustry());
            originalUser.setIdentityCard(user.getIdentityCard());
            
            // 不允许本人修改角色
            if (user.getRole() != null && !user.getRole().equals(originalUser.getRole())) {
                return Result.error("无权修改自己的角色");
            }
        }
        
        // 处理密码更新
        if (user.getPassword() != null && !user.getPassword().startsWith("$2a$")) {
            originalUser.setPassword(PasswordUtil.encode(user.getPassword()));
        } else if (user.getPassword() != null) {
            originalUser.setPassword(user.getPassword());
        }

        boolean updated = userService.updateById(originalUser);
        if (!updated) {
            return Result.error("更新失败");
        }
        return Result.success();
    }
    /**
     * 修改密码（仅修改当前登录用户的密码）
     * @param changePasswordDTO 包含旧密码和新密码
     * @return
     */
    @PutMapping("/update/changePassword")
    @SaCheckLogin // 必须登录
    public Result changePassword(@RequestBody ChangePasswordDTO changePasswordDTO) {
        if (changePasswordDTO == null ||
                changePasswordDTO.getOldPassword() == null ||
                changePasswordDTO.getNewPassword() == null) {
            return Result.error("旧密码或新密码不能为空");
        }
        Long currentUserId = StpUtil.getLoginIdAsLong();
        User currentUser = userService.getById(currentUserId);
        if (currentUser == null) {
            return Result.error("用户不存在");
        }
        // 验证旧密码是否正确
        if (!PasswordUtil.matches(changePasswordDTO.getOldPassword(), currentUser.getPassword())) {
            return Result.error("旧密码错误");
        }
        // 加密新密码
        String encodedNewPassword = PasswordUtil.encode(changePasswordDTO.getNewPassword());
        currentUser.setPassword(encodedNewPassword);
        // 更新数据库
        boolean updated = userService.updateById(currentUser);
        if (!updated) {
            return Result.error("密码修改失败");
        }
        return Result.success("密码修改成功");
    }

    /**
     * 单个用户查询
     * @param id
     * @return
     */
    @GetMapping("/get/{id}")
    @SaCheckLogin
    public Result getOne(@PathVariable Long id) {
        User user = userService.getById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }
        return Result.success(user);
    }

    /**
     * 当前用户信息(简化版)
     * @return
     */
    @GetMapping("/getOneCurrent")
    @SaCheckLogin
    public Result getOneCurrent(){
        Long currentUserId = StpUtil.getLoginIdAsLong();
        return Result.success(getOne(currentUserId));
    }

    /**
     * 个人信息
     * @return
     */
    @GetMapping("/profile")
    @SaCheckLogin
    public Result getProfile() {
        Long currentUserId = StpUtil.getLoginIdAsLong();
        User currentUser = userService.getById(currentUserId);
        if (currentUser == null) {
            return Result.error("用户不存在");
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(currentUser, userVO); // 自动拷贝同名字段
        return Result.success(userVO);
    }
    /**
     * 分页
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @GetMapping("/page")
    @SaCheckRole("ADMIN")
    public Result page(@RequestParam(defaultValue = "1") Integer pageNum,
                       @RequestParam(defaultValue = "5") Integer pageSize) {
        return Result.success(userService.page(new Page<>(pageNum, pageSize)));
    }

    /**
     * 列表查询
     *
     * @return
     */
    @GetMapping("/list")
    @SaCheckRole("ADMIN")
    public Result list() {
        return Result.success(userService.list());
    }

    /**
     * 删除用户
     * @param id
     * @return
     */
    @DeleteMapping("/delete/{id}")
    @SaCheckRole("ADMIN")
    public Result delete(@PathVariable Long id) {
        // 如果删除的是在线用户，需要将其从在线列表中移除
        onlineUserService.removeUser(id);
        if (!userService.removeById(id)) {
            return Result.error("删除失败");
        }
        return Result.success();
    }
    
    /**
     * 获取在线用户数量
     * @return
     */
    @GetMapping("/online/count")
    @SaCheckRole("ADMIN")
    public Result getOnlineUserCount() {
        return Result.success(onlineUserService.getOnlineUserCount());
    }
    
    /**
     * 用户登出
     * @return
     */
    @PostMapping("/logout")
    @SaCheckLogin
    public Result logout() {
        Long userId = StpUtil.getLoginIdAsLong();
        StpUtil.logout();
        onlineUserService.removeUser(userId);
        return Result.success("登出成功");
    }
}
